package dcartes.plot;// "Java Tech"
//  Code provided with book for educational purposes only.
//  No warranty or guarantee implied.
//  This code freely available. No copyright claimed.
//  2003


import java.awt.Graphics;


/**
 *  Draws a set of functions within the plotting area.
 *  Instances of subclasses of DrawFunction each draw
 *  their respective function on the panel.
 */
public class DrawPanel extends PlotPanel
{
  String fTitle = "Debye-Scherrer";
  String fXLabel= " Intensity x Angle of Incidence";

  // Array of functions to draw.
  DrawFunction [] fDrawFunctions;

  // These numbers determine the axes ranges.
  double fYDataMin = 0.0;
  double fYDataMax = 1.0;
  double fXDataMin = 0.0;
  double fXDataMax = 1.0;

  // Arrays to use for plotting axes scale values
  double [] fXScaleValue;
  double [] fYScaleValue;

  // Number of values for the x and y axes scales.
  int fNumYScaleValues = 2;
  int fNumXScaleValues = 5;

  /**
    *  Set the upper and lower limits for the drawing area.
    *  Assumes the number of elements in the arrays are
    *  the same.
   **/
  public DrawPanel (double y_data_min, double y_data_max,
                    double x_data_min, double x_data_max,
                    DrawFunction [] draw_functions) {
    fDrawFunctions = draw_functions;

    fYDataMax = y_data_max;
    fXDataMax = x_data_max;

    fYDataMin = y_data_min;
    fXDataMin = x_data_min;

    getScaling ();

  } // ctor


  /**
    * Get the values for the scaling numbers on
    * the plot axes.
   **/
  void getScaling () {

    fYScaleValue = new double[fNumYScaleValues];

    // Use lowest value of 0;
    fYScaleValue[0] = fYDataMin;
    fYScaleValue[fNumYScaleValues-1] = fYDataMax;

    // Then calculate the difference between the values
    double range = fYScaleValue[fNumYScaleValues-1]
                        - fYScaleValue[0];
    double del = range/ (fNumYScaleValues-1);

    // Now set the intermediate scale values.
    for (int i=1; i <  (fNumYScaleValues-1); i++) {
        fYScaleValue[i] = i * del + fYScaleValue[0];
    }

    fXScaleValue = new double[fNumXScaleValues];
    // First get the low and high values;
    fXScaleValue[0] = fXDataMin;
    fXScaleValue[fNumXScaleValues-1] = fXDataMax;

    // Then calculate the difference between the values
    range = fXScaleValue[fNumXScaleValues-1]
                        - fXScaleValue[0];
    del = range/ (fNumXScaleValues-1);

    // Now set the intermediate scale values.
    for (int i=1; i <  (fNumXScaleValues-1); i++) {
        fXScaleValue[i] = i * del + fXScaleValue[0];
    }

  } // getScaling

  /**
    *  Invoke the draw method for the list of
    *  DrawFunction instances. <br><br>
    *  Note that the frame area is clipped so further use of
    *  g will also be clipped to show only drawing within the
    *  scaled frame area.
   **/
  void paintContents (Graphics g) {
    if (fDrawFunctions == null) return;

    // Draw the numbers along the axes
    drawAxesNumbers (g, fXScaleValue, fYScaleValue);

    // Keep drawing within the frame box
    g.setClip (fFrameX, fFrameY, fFrameWidth, fFrameHeight);

    // Now loop through all the
    for (int i=0; i < fDrawFunctions.length; i++) {
         fDrawFunctions[i].draw (
                          g,
                          fFrameX,     fFrameY,
                          fFrameWidth, fFrameHeight,
                          fXScaleValue,fYScaleValue);
    }
  } // paintContents


  /** Return the plot title. **/
  String getTitle ()
  {  return fTitle;}


  /** Return the x axis label. **/
  String getXLabel ()
  {  return fXLabel;}


  // Additional methods for setting the title and label

  /** Set plot title. **/
  void setTitle (String title)
  {  fTitle = title;}


  /** Set x axis label.**/
  void setXLabel (String x_label)
  {  fXLabel = x_label;}


  /** Set scaling limits for axes. **/
  void setScaleLimits (double y_data_min, double y_data_max,
                       double x_data_min, double x_data_max) {
    this.fYDataMax = y_data_max;
    this.fXDataMax = x_data_max;

    this.fYDataMin = y_data_min;
    this.fXDataMin = x_data_min;

    getScaling ();
  }


  /**  Pass a new array of DrawFunction objects. **/
  void setDrawFunctions (DrawFunction [] draw_functions){
    fDrawFunctions = draw_functions;
  }

} // class DrawPanel

